<template>
  <div class="static basic-editor">
    <my-toolbar
      class="toolbar"
      mode="default"
      :editor="editorRef"
      :default-config="toolbarConfig"
    ></my-toolbar>
    <my-editor
      v-model="content"
      class="editor"
      mode="default"
      :default-config="editorConfig"
      :style="{
        height
      }"
      @on-created="handleCreated"
    ></my-editor>
  </div>
</template>

<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css'

import type { IEditorConfig, IToolbarConfig } from '@wangeditor/editor'
import { Boot } from '@wangeditor/editor'
import {
  Editor as MyEditor,
  Toolbar as MyToolbar
} from '@wangeditor/editor-for-vue'
import markdownModule from '@wangeditor/plugin-md' //使用基本的 markdown
const configStore = useConfigStore()
interface IEmit {
  (event: 'update:modelValue', value: string): void
  (event: 'validate'): void
}

interface IProps {
  modelValue: string
  width?: string
  height?: string
  placeholder?: string
  maxLength?: number
}

const emit = defineEmits<IEmit>()
const props = withDefaults(defineProps<IProps>(), {
  width: '950px',
  height: '400px',
  placeholder: useI18nContent('common.global.input'),
  maxLength: 0
})
//在创建编辑器之前注册
const editorRef = shallowRef()
Boot.registerModule(markdownModule)
const content = useVModel(props, 'modelValue', emit)
watch(content, () => {
  if (content.value && editorRef?.value?.getText()) emit('validate')
})
const toolbarConfig: Partial<IToolbarConfig> = {
  toolbarKeys: [
    'headerSelect',
    'fontFamily',
    'bold',
    'italic',
    'underline',
    'through',
    'lineHeight',
    'justifyLeft',
    'justifyRight',
    'justifyCenter',
    'justifyJustify',
    'numberedList',
    'blockquote',
    'code',
    'emotion',
    'insertImage',
    'uploadImage',
    'insertTable',
    {
      key: 'group-link',
      title: 'link',
      menuKeys: ['insertLink', 'editLink', 'unLink', 'viewLink']
    }
  ]
}

const editorConfig: Partial<IEditorConfig> = {
  placeholder: props.placeholder,
  maxLength: props.maxLength,
  MENU_CONF: {
    uploadImage: {
      customUpload: uploadImageFunc()
    }
  }
}
type InsertFnType = (url: string, poster?: string) => void
function uploadImageFunc() {
  return (file: File, insertFn: InsertFnType) => {
    return new Promise((resolve, reject) => {
      const formData = new FormData()
      formData.append('file', file)
      fetch(configStore.apiUrl + '/v1/upload/file', {
        method: 'POST',
        body: formData
      })
        .then(res => res.json())
        .then(res => {
          const url = configStore.apiUrl + res.data.url
          insertFn(url)
          resolve(res.data)
        })
        .catch(err => {
          reject(err)
        })
    })
  }
}
function handleCreated(editor) {
  editorRef.value = editor
}
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})
</script>

<style scoped lang="scss">
.basic-editor {
  width: v-bind('$props.width');
  border: 1px solid #dbdde2;
  border-radius: 4px;
  overflow: hidden;
  font-size: 15px;
  line-height: 24px;

  .toolbar {
    border-bottom: 1px solid #dbdde2;
  }

  .editor {
    @apply w-full;
  }
}
</style>

<style>
.basic-editor .w-e-text-container p {
  margin: 0 !important;
}

.basic-editor .w-e-text-container {
  padding: 8px 0 0;
}

.basic-editor .w-e-text-placeholder {
  top: 9px;
}
</style>
